package com.bitejiuyeke.job_publish.service.impl;

import com.bitejiuyeke.job_publish.common.AppResult;
import com.bitejiuyeke.job_publish.common.PageResult;
import com.bitejiuyeke.job_publish.common.ResultCode;
import com.bitejiuyeke.job_publish.dao.OfferMapper;
import com.bitejiuyeke.job_publish.enums.DeleteStateEnum;
import com.bitejiuyeke.job_publish.enums.OfferStateEnum;
import com.bitejiuyeke.job_publish.enums.SendRecordStateEnum;
import com.bitejiuyeke.job_publish.exception.ApplicationException;
import com.bitejiuyeke.job_publish.model.Offer;
import com.bitejiuyeke.job_publish.model.SendRecord;
import com.bitejiuyeke.job_publish.service.IJobService;
import com.bitejiuyeke.job_publish.service.IOfferService;
import com.bitejiuyeke.job_publish.service.ISendRecordService;
import com.bitejiuyeke.job_publish.service.IUserService;
import com.bitejiuyeke.job_publish.utils.JsonUtils;
import com.bitejiuyeke.job_publish.utils.RedisUtils;
import com.bitejiuyeke.job_publish.utils.StringUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Author 比特就业课
 */
@Slf4j
@Service
public class OfferServiceImpl implements IOfferService {

    // 有效时间 24 小时
    private static final int EFFECTIVE_TIME = 60 * 60 * 24;

    private static final String KEY_CODE_PREFIX = "KEY_OFFER:ID:";

    @Resource
    private RedisUtils redisUtils;
    @Resource
    private OfferMapper mapper;
    @Resource
    private IUserService userService;
    @Resource
    private IJobService jobService;
    @Resource
    private ISendRecordService sendRecordService;

    @Override
    public void create(Offer offer) {
        // 校验
        if (offer == null || offer.getUserId() == null || offer.getUserId() <= 0
                || offer.getJobId() == null || offer.getJobId() <= 0
                || offer.getSendRecordId() == null || offer.getSendRecordId() <= 0) {
            log.warn("新增Offer记录失败. " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        // 设置默认值
        offer.setState((byte) OfferStateEnum.OFFERED.getCode());
        offer.setDeleteState((byte) DeleteStateEnum.NORMAL.getCode());
        Date now = new Date();
        offer.setCreateTime(now);
        offer.setUpdateTime(now);
        // 写入数据库
        int row = mapper.insertSelective(offer);
        if (row != 1) {
            log.error("新增Offer记录失败. " + ResultCode.ERROR_SERVICES);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
    }

    @Override
    public Offer selectById(Long id) {
        // 校验
        if (id == null || id <= 0) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 查询缓存
        Offer offer = getFromCache(id);
        if (offer != null) {
            return offer;
        }
        // 从数据库中查询
        offer = mapper.selectByPrimaryKey(id);
        if (offer == null) {
            return null;
        }
        // 查询用户和投递记录
        SendRecord sendRecord = sendRecordService.selectById(offer.getSendRecordId());
        offer.setSendRecord(sendRecord);
        // 设置到缓存
        setToCache(offer);
        // 返回
        return offer;
    }

    @Override
    public void modifyState(Offer record) {
        if (record.getId() == null || record.getId() <= 0
                || record.getUserId() == null || record.getUserId() <= 0
                || record.getState() == null || OfferStateEnum.valueOf(record.getState()) == null) {
            log.warn("设置状态失败. " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 状态
        OfferStateEnum stateEnum = OfferStateEnum.valueOf(record.getState());
        // 查询Offer记录
        Offer offer = selectById(record.getId());
        // 校验Offer
        if (offer == null) {
            log.warn("设置Offer状态失败. " + ResultCode.FAILED_NOT_EXISTS);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_NOT_EXISTS));
        }
        // 是否自己的Offer
        if (offer.getUserId() != record.getUserId()) {
            log.warn("设置Offer状态失败. " + ResultCode.FAILED_NOT_PERMISSION);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_NOT_PERMISSION));
        }
        if (stateEnum.getCode() <= offer.getState()) {
            log.warn("不能回退Offer状态. offerId = {}", offer.getId());
            throw new ApplicationException(AppResult.failed("不能回退Offer状态."));
        }
        // 更新Offer状态
        Offer update = new Offer();
        update.setId(offer.getId());
        update.setState((byte) stateEnum.getCode());
        Date now = new Date();
        update.setUpdateTime(now);
        int row = mapper.updateByPrimaryKeySelective(update);
        if (row != 1) {
            log.warn("设置Offer状态失败. " + ResultCode.ERROR_SERVICES);
            throw new ApplicationException(AppResult.failed("设置Offer状态失败."));
        }

        SendRecord sendRecord = new SendRecord();
        sendRecord.setId(offer.getSendRecordId());
        sendRecord.setReceiveUserId(offer.getSendRecord().getReceiveUserId());
        // 更新投递记录
        switch (stateEnum) {
            // 设置状态
            case ACCEPTED -> sendRecord.setState((byte) SendRecordStateEnum.ACCEPTED.getCode());
            case REJECTED -> sendRecord.setState((byte) SendRecordStateEnum.REJECTED.getCode());
        }
        // 更新状态
        sendRecordService.modifyState(sendRecord);
        // 更新缓存
        redisUtils.del(buildKey(offer.getId()));
    }

    @Override
    public int selectTotalByUser(Offer record) {
        // 校验
        if (record == null || record.getPageSize() == null || record.getOffset() == null) {
            log.info("获取用户Offer总数失败. " + ResultCode.FAILED_PARAMS_VALIDATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 查询
        int totalRecord = mapper.selectTotalByUser(record);
        return totalRecord;
    }

    @Override
    public PageResult<Offer> selectPageByUser(Offer record) {
        // 获取总数
        int totalRecord = selectTotalByUser(record);
        // 分页结果对象
        PageResult<Offer> pageResult = new PageResult<>(record.getPageNum(), record.getPageSize(),
                totalRecord);
        // 分页数据列表
        List<Offer> list = mapper.selectPageByUser(record);
        pageResult.setRows(list);
        // 返回结果
        return pageResult;
    }

    private String buildKey(Long id) {
        return KEY_CODE_PREFIX + id;
    }

    // 从缓存中获取数据
    private Offer getFromCache(Long id) {
        // 获取缓存中的数据
        String content = (String) redisUtils.get(buildKey(id));
        if (StringUtils.isEmpty(content)) {
            // 缓存中不存在
            return null;
        }
        // 缓存中存在直接返回
        Offer offer = JsonUtils.readValue(content, Offer.class);
        return offer;
    }

    // 向缓存中设置数据
    private void setToCache(Offer offer) {
        if (offer == null || offer.getId() == null) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        redisUtils.set(buildKey(offer.getId()), JsonUtils.writeValueAsString(offer), EFFECTIVE_TIME);
    }
}
